package top.lixunda.ecommerce.server.user.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.OrderByDTO;
import top.lixunda.ecommerce.server.user.api.entity.db.AccountDO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 账户信息查询DTO
 *
 * @author lixunda
 * @version time:2020/4/14 15:35
 */
@ApiModel("账户信息查询DTO")
@Data
@EqualsAndHashCode(callSuper = true)
public class AccountQueryDTO extends OrderByDTO
        implements ILambdaQueryWrapperDTO<AccountDO> {

    /**
     * 官方用户唯一账户
     */
    @ApiModelProperty("官方用户唯一账户")
    private List<Integer> account;

    /**
     * 用户类型，如管理员，店铺用户，普通用户
     */
    @ApiModelProperty("用户类型，，如管理员，店铺用户，普通用户")
    private List<String> userType;

    /**
     * 注册时间
     */
    @ApiModelProperty("注册时间")
    private LocalDateTime createTimeStart;

    /**
     * 注册时间
     */
    @ApiModelProperty("注册时间")
    private LocalDateTime createTimeEnd;

    /**
     * 最后一次更新时间
     */
    @ApiModelProperty("最后一次更新时间")
    private LocalDateTime updateTimeStart;

    /**
     * 最后一次更新时间
     */
    @ApiModelProperty("最后一次更新时间")
    private LocalDateTime updateTimeEnd;

    /**
     * token
     */
    @ApiModelProperty("token")
    private String token;

    /**
     * 密码提示问题
     */
    @ApiModelProperty("密码提示问题")
    private String passHint;

    /**
     * 当前账户是否可用
     */
    @ApiModelProperty("当前账户是否可用")
    private Integer forbidden;

    /**
     * 排序字段映射
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private static final Map<String, SFunction<AccountDO, ?>> ACCOUNT_COLUMNS =
            new ImmutableMap.Builder<String, SFunction<AccountDO, ?>>()
                    .put("account", AccountDO::getAccount)
                    .put("password", AccountDO::getPassword)
                    .put("userType", AccountDO::getUserType)
                    .put("createTime", AccountDO::getCreateTime)
                    .put("updateTime", AccountDO::getUpdateTime)
                    .put("token", AccountDO::getToken)
                    .put("passHint", AccountDO::getPassHint)
                    .put("passHintAns", AccountDO::getPassHintAns)
                    .put("forbidden", AccountDO::getForbidden)
                    .put("forbiddenDesc", AccountDO::getForbiddenDesc)
                    .put("remark", AccountDO::getRemark)
                    .build();

    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @Override
    public LambdaQueryWrapper<AccountDO> toWrapper() {
        LambdaQueryWrapper<AccountDO> wrapper = new LambdaQueryWrapper<>();
        if (ObjectValidators.isNotEmpty(account)) {
            wrapper.and(innerWrapper ->
                    account.forEach(item -> innerWrapper.or().eq(AccountDO::getAccount, item)));
        }
        if (ObjectValidators.isNotEmpty(userType)) {
            wrapper.and(innerWrapper ->
                    userType.forEach(item -> innerWrapper.or().eq(AccountDO::getUserType, item)));
        }
        if (ObjectValidators.isNotEmpty(createTimeStart)) {
            wrapper.ge(AccountDO::getCreateTime, createTimeStart);
        }
        if (ObjectValidators.isNotEmpty(createTimeEnd)) {
            wrapper.le(AccountDO::getCreateTime, createTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(updateTimeStart)) {
            wrapper.ge(AccountDO::getUpdateTime, updateTimeStart);
        }
        if (ObjectValidators.isNotEmpty(updateTimeEnd)) {
            wrapper.le(AccountDO::getUpdateTime, updateTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(token)) {
            wrapper.le(AccountDO::getToken, token);
        }
        if (ObjectValidators.isNotEmpty(passHint)) {
            wrapper.le(AccountDO::getPassHint, passHint);
        }
        if (ObjectValidators.isNotEmpty(forbidden)) {
            wrapper.le(AccountDO::getForbidden, forbidden);
        }
        dealWithOrderBy(wrapper, ACCOUNT_COLUMNS);
        return wrapper;
    }
}
